/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pointfinder;

import com.jme3.bounding.BoundingBox;
import com.jme3.bounding.BoundingSphere;
import com.jme3.bounding.BoundingVolume;
import com.jme3.collision.CollisionResult;
import com.jme3.collision.CollisionResults;
import com.jme3.math.Ray;
import com.jme3.math.Vector3f;
import data.Vector3i;
import com.jme3.scene.Geometry;
import computing.EasyFind;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

/**
 *
 * @author oxplay
 */
public class GeometryContainer extends AbstractPointContainer {

    private Map<Vector3i, PointEntity> points = new HashMap<Vector3i, PointEntity>();
    private Vector3i startVect = new Vector3i(0, 0, 0);
    private Vector3i endVect = new Vector3i(0, 0, 0);
    private Vector3f center3f = new Vector3f(0, 0, 0);
    private BoundingVolume bounding;
    private int x, y, z;

    public GeometryContainer(Geometry geom) {
        bounding = geom.getWorldBound();
        if (bounding instanceof BoundingSphere) {
            BoundingSphere bsphere = (BoundingSphere) bounding;
            center3f = bsphere.getCenter();
            startVect = new Vector3i(bsphere.getCenter().subtract(bsphere.getRadius(), bsphere.getRadius(), bsphere.getRadius()));
            endVect = new Vector3i(bsphere.getCenter().add(bsphere.getRadius(), bsphere.getRadius(), bsphere.getRadius()));
        } else if (bounding instanceof BoundingBox) {
            BoundingBox bbox = (BoundingBox) bounding;
            center3f = bbox.getCenter();
            startVect = new Vector3i(bbox.getCenter().subtract(bbox.getXExtent(), bbox.getYExtent(), bbox.getZExtent()));
            endVect = new Vector3i(bbox.getCenter().add(bbox.getXExtent(), bbox.getYExtent(), bbox.getZExtent()));
        }
        if (geom.getUserData("EasyFindType") == null || !geom.getUserData("EasyFindType").equals(EasyFind.NODETYPE_CHARACTER)) {
            examineBlockades(geom);
            examineTop(geom);
        }
    }

    private void examineBlockades(Geometry geom) {
        for (x = startVect.x; x <= endVect.x; x++) {
            for (z = startVect.z; z <= endVect.z; z++) {
                for (y = startVect.y; y <= endVect.y; y++) {
                    Vector3i actVect = new Vector3i(x, y, z);
                    if (bounding.contains(actVect.getVector3f())) {
                        points.put(actVect, PointEntity.BLOCKADE);
                    }
                }
            }
        }
    }

    private void examineTop(Geometry geom) {
        System.out.println("startVect: "+startVect+" endVect: "+endVect);
        for (x = startVect.x; x <= endVect.x; x++) {
            for (z = startVect.z; z <= endVect.z; z++) {
                Vector3f origin = new Vector3f(x, endVect.y+1f, z);
                Vector3f direction = new Vector3f(x, startVect.y, z);
                direction.subtractLocal(origin).normalizeLocal();
                Ray mouseRay = new Ray(origin, direction);
                CollisionResults results = new CollisionResults();
                geom.collideWith(mouseRay, results);
                if (results.size() > 0) {
                    CollisionResult collision = results.getClosestCollision();
                    Vector3i point = new Vector3i(collision.getContactPoint());
                    points.put(point, PointEntity.MOVEABLE);
                }
            }
        }
    }

    public PointEntity getPoint(Vector3i vect) {
        PointEntity entity = points.get(vect);
        if (entity != null) {
            return entity;
        }
        return PointEntity.NEUTRAL;
    }

    @Override
    public ArrayList<Vector3i> getAllPoints() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Deprecated
    @Override
    public Set<Vector3i> getPointsSection(Vector3i from, Vector3i to) {
        Set<Vector3i> list = new HashSet<Vector3i>();
        for (Iterator<Vector3i> it = points.keySet().iterator(); it.hasNext();) {
            Vector3i vect = it.next();
            list.add(vect);
        }
        return list;
    }
}
